/*
 * 版权所有 (c) 2024 坚果派
 * 作者：坚果派
 * 公众号：nutpi
 * 电话：17752170152
 * 官网：https://www.nutpi.net/
 * 
 * 保留所有权利。
 */

import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'dart:async';

/// 应用程序的入口点，启动 Flutter 应用。
///
/// 调用 `runApp` 方法并传入 `MyApp` 组件，
/// 以构建应用的 UI。

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '我的世界小游戏',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        useMaterial3: true,
      ),
      home: const MinecraftGame(title: '我的世界小游戏'),
    );
  }
}

class MinecraftGame extends StatefulWidget {
  const MinecraftGame({super.key, required this.title});

  final String title;

  @override
  State<MinecraftGame> createState() => _MinecraftGameState();
}

class _MinecraftGameState extends State<MinecraftGame> {
  // 游戏世界大小
  static const int worldWidth = 10;
  static const int worldHeight = 10;
  static const int worldDepth = 3;

  // 方块类型
  static const int blockEmpty = 0;
  static const int blockDirt = 1;
  static const int blockGrass = 2;
  static const int blockStone = 3;
  static const int blockWood = 4;
  static const int blockLeaves = 5;
  static const int blockWater = 6;
  static const int blockSand = 7;
  static const int blockRedstone = 8;
  static const int blockGold = 9;
  static const int blockDiamond = 10;
  static const int blockIron = 11;

  // 当前选中的方块类型
  int selectedBlockType = blockDirt;

  // 游戏世界数据
  late List<List<List<int>>> worldBlocks;

  // 生物系统
  List<Animal> animals = [];
  Timer? animalMovementTimer;

  // 背包系统
  Map<int, int> inventory = {};
  bool isInventoryOpen = false;

  // 相机位置和角度
  double cameraX = worldWidth / 2;
  double cameraY = worldHeight / 2;
  double cameraZ = -5.0;
  double cameraRotX = 0.0;
  double cameraRotY = 0.0;

  // 游戏模式
  bool isDestroyMode = false;

  // 昼夜循环
  bool isDayTime = true;
  Timer? dayNightTimer;

  @override
  void initState() {
    super.initState();
    initWorld();
    startDayNightCycle();
    spawnAnimals();
    startAnimalMovement();
  }

  // 启动昼夜循环
  void startDayNightCycle() {
    dayNightTimer = Timer.periodic(const Duration(seconds: 30), (timer) {
      setState(() {
        isDayTime = !isDayTime;
      });
    });
  }

  @override
  void dispose() {
    dayNightTimer?.cancel();
    animalMovementTimer?.cancel();
    super.dispose();
  }

  // 生成动物
  void spawnAnimals() {
    final random = math.Random();
    // 生成3-5只动物
    final animalCount = random.nextInt(3) + 3;

    for (int i = 0; i < animalCount; i++) {
      final animalX = random.nextDouble() * worldWidth;
      final animalY = random.nextDouble() * worldHeight;
      final animalType = random.nextInt(3); // 0: 羊, 1: 猪, 2: 鸡

      animals.add(Animal(
        x: animalX,
        y: animalY,
        type: animalType,
      ));
    }
  }

  // 启动动物移动
  void startAnimalMovement() {
    animalMovementTimer = Timer.periodic(const Duration(seconds: 2), (timer) {
      setState(() {
        final random = math.Random();
        for (var animal in animals) {
          // 随机移动
          animal.x += (random.nextDouble() - 0.5) * 0.5;
          animal.y += (random.nextDouble() - 0.5) * 0.5;

          // 确保不超出边界
          animal.x = animal.x.clamp(0.0, worldWidth.toDouble() - 1);
          animal.y = animal.y.clamp(0.0, worldHeight.toDouble() - 1);
        }
      });
    });
  }

  // 收集方块到背包
  void collectBlock(int blockType) {
    setState(() {
      if (inventory.containsKey(blockType)) {
        inventory[blockType] = (inventory[blockType] ?? 0) + 1;
      } else {
        inventory[blockType] = 1;
      }
    });
  }

  // 从背包使用方块
  bool useBlockFromInventory(int blockType) {
    if (inventory.containsKey(blockType) && (inventory[blockType] ?? 0) > 0) {
      setState(() {
        inventory[blockType] = (inventory[blockType] ?? 0) - 1;
        if (inventory[blockType] == 0) {
          inventory.remove(blockType);
        }
      });
      return true;
    }
    return false;
  }

  // 初始化游戏世界
  void initWorld() {
    worldBlocks = List.generate(
      worldWidth,
      (x) => List.generate(
        worldHeight,
        (y) => List.generate(
          worldDepth,
          (z) {
            // 创建基本地形
            if (z == 0) {
              // 顶层随机生成不同地形
              final random = math.Random();
              final terrainType = random.nextInt(10);

              if (terrainType < 6) return blockGrass; // 60%几率是草地
              if (terrainType < 8) return blockSand; // 20%几率是沙子
              if (terrainType < 9) return blockWater; // 10%几率是水
              return blockWood; // 10%几率是木头
            }
            if (z == 1) return blockDirt; // 中间是泥土
            return blockStone; // 底层是石头
          },
        ),
      ),
    );

    // 随机生成一些树
    final random = math.Random();
    for (int i = 0; i < 3; i++) {
      final treeX = random.nextInt(worldWidth);
      final treeY = random.nextInt(worldHeight);

      // 只在草地上生成树
      if (worldBlocks[treeX][treeY][0] == blockGrass) {
        // 树干
        placeBlock(treeX, treeY, 0, blockWood);

        // 树叶
        for (int dx = -1; dx <= 1; dx++) {
          for (int dy = -1; dy <= 1; dy++) {
            placeBlock(treeX + dx, treeY + dy, -1, blockLeaves);
          }
        }
      }
    }
  }

  // 放置方块
  void placeBlock(int x, int y, int z, int blockType) {
    if (x >= 0 &&
        x < worldWidth &&
        y >= 0 &&
        y < worldHeight &&
        z >= 0 &&
        z < worldDepth) {
      setState(() {
        worldBlocks[x][y][z] = blockType;
      });
    }
  }

  // 移除方块
  void removeBlock(int x, int y, int z) {
    if (x >= 0 &&
        x < worldWidth &&
        y >= 0 &&
        y < worldHeight &&
        z >= 0 &&
        z < worldDepth) {
      setState(() {
        worldBlocks[x][y][z] = blockEmpty;
      });
    }
  }

  // 获取方块颜色
  Color getBlockColor(int blockType) {
    switch (blockType) {
      case blockDirt:
        return Colors.brown;
      case blockGrass:
        return Colors.green.shade800;
      case blockStone:
        return Colors.grey.shade700;
      case blockWood:
        return Colors.brown.shade800;
      case blockLeaves:
        return Colors.green.shade600;
      case blockWater:
        return Colors.blue.shade500;
      case blockSand:
        return Colors.yellow.shade600;
      case blockRedstone:
        return Colors.red.shade600;
      case blockGold:
        return Colors.yellow.shade400;
      case blockDiamond:
        return Colors.lightBlue.shade300;
      case blockIron:
        return Colors.grey.shade400;
      default:
        return Colors.transparent;
    }
  }

  // 处理方块点击
  void handleBlockTap(int x, int y, int z) {
    if (isDestroyMode) {
      // 收集被破坏的方块
      final blockType = worldBlocks[x][y][z];
      if (blockType != blockEmpty) {
        collectBlock(blockType);
      }
      removeBlock(x, y, z);
    } else {
      // 在点击位置上方放置方块
      if (useBlockFromInventory(selectedBlockType) ||
          selectedBlockType == blockDirt) {
        // 泥土无限供应，其他方块需要从背包中使用
        placeBlock(x, y, z - 1, selectedBlockType);
      }
    }
  }

  // 计算点击位置对应的方块坐标
  void handleScreenTap(TapDownDetails details, Size size) {
    // 获取点击位置相对于画布中心的坐标
    final dx = details.localPosition.dx - size.width / 2;
    final dy = details.localPosition.dy - size.height / 2;

    // 简单的反向计算，将屏幕坐标转换为世界坐标
    // 这里的计算是简化的，实际上应该考虑相机旋转等因素
    final blockSize = 30.0;
    final x = (dx / blockSize + cameraX).round();
    final y = (dy / blockSize + cameraY).round();

    // 从上到下检查是否有方块
    for (int z = 0; z < worldDepth; z++) {
      if (x >= 0 &&
          x < worldWidth &&
          y >= 0 &&
          y < worldHeight &&
          worldBlocks[x][y][z] != blockEmpty) {
        handleBlockTap(x, y, z);
        break;
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Row(
          children: [
            Image.asset(
              'assets/icon/minecraft_block_icon.png',
              width: 30,
              height: 30,
            ),
            const SizedBox(width: 10),
            Text(widget.title),
          ],
        ),
        actions: [
          // 昼夜状态显示
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Icon(
              isDayTime ? Icons.wb_sunny : Icons.nightlight_round,
              color: isDayTime ? Colors.orange : Colors.indigo,
            ),
          ),
          // 背包按钮
          IconButton(
            icon: const Icon(Icons.inventory),
            onPressed: () {
              setState(() {
                isInventoryOpen = !isInventoryOpen;
              });
            },
          ),
        ],
      ),
      body: Column(
        children: [
          Expanded(
            flex: 4,
            child: GestureDetector(
              onPanUpdate: (details) {
                setState(() {
                  // 旋转相机
                  cameraRotY += details.delta.dx * 0.01;
                  cameraRotX += details.delta.dy * 0.01;
                });
              },
              onTapDown: (details) {
                // 处理点击放置/破坏方块
                handleScreenTap(details, MediaQuery.of(context).size);
              },
              child: Stack(
                children: [
                  // 游戏世界
                  CustomPaint(
                    painter: MinecraftWorldPainter(
                      worldBlocks: worldBlocks,
                      cameraX: cameraX,
                      cameraY: cameraY,
                      cameraZ: cameraZ,
                      cameraRotX: cameraRotX,
                      cameraRotY: cameraRotY,
                      getBlockColor: getBlockColor,
                      isDayTime: isDayTime,
                      animals: animals,
                    ),
                    child: Container(),
                  ),
                  // 模式提示
                  Positioned(
                    top: 10,
                    left: 10,
                    child: Container(
                      padding: const EdgeInsets.all(8),
                      decoration: BoxDecoration(
                        color: Colors.black54,
                        borderRadius: BorderRadius.circular(5),
                      ),
                      child: Text(
                        isDestroyMode ? '破坏模式' : '建造模式',
                        style: const TextStyle(color: Colors.white),
                      ),
                    ),
                  ),
                  // 背包界面
                  if (isInventoryOpen)
                    Positioned(
                      top: 50,
                      right: 10,
                      child: Container(
                        width: 200,
                        padding: const EdgeInsets.all(8),
                        decoration: BoxDecoration(
                          color: Colors.black87,
                          borderRadius: BorderRadius.circular(5),
                        ),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            const Text(
                              '背包',
                              style: TextStyle(
                                  color: Colors.white,
                                  fontWeight: FontWeight.bold),
                            ),
                            const SizedBox(height: 8),
                            ...inventory.entries
                                .map((entry) => Padding(
                                      padding: const EdgeInsets.symmetric(
                                          vertical: 4),
                                      child: Row(
                                        children: [
                                          Container(
                                            width: 20,
                                            height: 20,
                                            color: getBlockColor(entry.key),
                                          ),
                                          const SizedBox(width: 8),
                                          Text(
                                            'x${entry.value}',
                                            style: const TextStyle(
                                                color: Colors.white),
                                          ),
                                          const Spacer(),
                                          IconButton(
                                            icon: const Icon(Icons.add_circle,
                                                color: Colors.white, size: 20),
                                            onPressed: () {
                                              setState(() {
                                                selectedBlockType = entry.key;
                                                isDestroyMode = false;
                                                isInventoryOpen = false;
                                              });
                                            },
                                          ),
                                        ],
                                      ),
                                    ))
                                .toList(),
                          ],
                        ),
                      ),
                    ),
                ],
              ),
            ),
          ),
          // 控制面板
          Container(
            height: 150,
            color: Colors.grey.shade800,
            child: Column(
              children: [
                // 方块选择栏
                Expanded(
                  child: ListView(
                    scrollDirection: Axis.horizontal,
                    padding: const EdgeInsets.all(8),
                    children: [
                      _buildBlockButton(blockDirt),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockGrass),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockStone),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockWood),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockLeaves),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockWater),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockSand),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockRedstone),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockGold),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockDiamond),
                      const SizedBox(width: 8),
                      _buildBlockButton(blockIron),
                    ],
                  ),
                ),
                // 功能按钮栏
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Wrap(
                    spacing: 8.0,
                    runSpacing: 8.0,
                    alignment: WrapAlignment.spaceEvenly,
                    children: [
                      // 切换模式按钮
                      ElevatedButton.icon(
                        onPressed: () {
                          setState(() {
                            isDestroyMode = !isDestroyMode;
                          });
                        },
                        icon: Icon(isDestroyMode ? Icons.build : Icons.delete),
                        label: Text(isDestroyMode ? '切换到建造' : '切换到破坏'),
                      ),
                      // 重置世界按钮
                      ElevatedButton.icon(
                        onPressed: () {
                          setState(() {
                            initWorld();
                          });
                        },
                        icon: const Icon(Icons.refresh),
                        label: const Text('重置世界'),
                      ),
                      // 切换昼夜按钮
                      ElevatedButton.icon(
                        onPressed: () {
                          setState(() {
                            isDayTime = !isDayTime;
                          });
                        },
                        icon: Icon(isDayTime
                            ? Icons.nightlight_round
                            : Icons.wb_sunny),
                        label: Text(isDayTime ? '切换到夜晚' : '切换到白天'),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildBlockButton(int blockType) {
    return GestureDetector(
      onTap: () {
        setState(() {
          selectedBlockType = blockType;
          // 选择方块时自动切换到建造模式
          isDestroyMode = false;
        });
      },
      child: Container(
        width: 50,
        height: 50,
        decoration: BoxDecoration(
          color: getBlockColor(blockType),
          border: Border.all(
            color:
                selectedBlockType == blockType ? Colors.yellow : Colors.black,
            width: 3,
          ),
        ),
      ),
    );
  }
}

// 动物类
class Animal {
  double x;
  double y;
  int type; // 0: 羊, 1: 猪, 2: 鸡

  Animal({required this.x, required this.y, required this.type});
}

// 方块渲染数据类
class BlockRenderData {
  final Offset position;
  final double depth;
  final int blockType;
  final double scale;
  final double blockSize;

  BlockRenderData({
    required this.position,
    required this.depth,
    required this.blockType,
    required this.scale,
    required this.blockSize,
  });
}

// 游戏世界绘制器
class MinecraftWorldPainter extends CustomPainter {
  final List<List<List<int>>> worldBlocks;
  final double cameraX;
  final double cameraY;
  final double cameraZ;
  final double cameraRotX;
  final double cameraRotY;
  final Function(int) getBlockColor;
  final bool isDayTime;
  final List<Animal> animals;

  MinecraftWorldPainter({
    required this.worldBlocks,
    required this.cameraX,
    required this.cameraY,
    required this.cameraZ,
    required this.cameraRotX,
    required this.cameraRotY,
    required this.getBlockColor,
    required this.isDayTime,
    required this.animals,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint();

    // 移动画布到中心
    canvas.translate(size.width / 2, size.height / 2);

    // 应用相机旋转
    canvas.rotate(cameraRotY);
    canvas.scale(1.0, 0.8 + 0.2 * math.cos(cameraRotX)); // 添加垂直方向的透视效果

    // 设置背景色（根据昼夜状态）
    canvas.drawRect(
      Rect.fromLTWH(-size.width / 2, -size.height / 2, size.width, size.height),
      Paint()
        ..color =
            isDayTime ? Colors.lightBlue.shade200 : Colors.indigo.shade900,
    );

    // 如果是白天，绘制太阳，否则绘制月亮
    if (isDayTime) {
      paint.color = Colors.yellow;
      canvas.drawCircle(
          Offset(size.width * 0.3, -size.height * 0.3), 30, paint);
    } else {
      paint.color = Colors.white.withOpacity(0.8);
      canvas.drawCircle(
          Offset(size.width * 0.3, -size.height * 0.3), 20, paint);
    }

    // 按照深度排序方块，使远处的方块先绘制
    List<BlockRenderData> renderList = [];

    for (int x = 0; x < worldBlocks.length; x++) {
      for (int y = 0; y < worldBlocks[x].length; y++) {
        for (int z = 0; z < worldBlocks[x][y].length; z++) {
          final blockType = worldBlocks[x][y][z];
          if (blockType == 0) continue; // 跳过空方块

          // 计算方块在屏幕上的位置
          final blockSize = 30.0;
          final dx = (x - cameraX) * blockSize;
          final dy = (y - cameraY) * blockSize;
          final dz = (z + cameraZ) * blockSize;

          // 计算方块到相机的距离，用于排序
          final distance = dx * dx + dy * dy + dz * dz;

          renderList.add(BlockRenderData(
            position: Offset(dx, dy),
            depth: distance,
            blockType: blockType,
            scale: 1.0 + dz / 500,
            blockSize: blockSize,
          ));
        }
      }
    }

    // 按深度排序，远处的方块先绘制
    renderList.sort((a, b) => b.depth.compareTo(a.depth));

    // 绘制所有方块
    for (var blockData in renderList) {
      // 设置方块颜色（根据昼夜状态调整亮度）
      Color blockColor = getBlockColor(blockData.blockType);
      if (!isDayTime) {
        // 降低夜间亮度
        final HSLColor hslColor = HSLColor.fromColor(blockColor);
        blockColor = hslColor
            .withLightness((hslColor.lightness * 0.6).clamp(0.0, 1.0))
            .toColor();
      }
      paint.color = blockColor;

      // 绘制方块（简化为2D矩形）
      canvas.drawRect(
        Rect.fromCenter(
          center: blockData.position,
          width: blockData.blockSize * blockData.scale,
          height: blockData.blockSize * blockData.scale,
        ),
        paint,
      );

      // 绘制方块边框
      final borderPaint = Paint()
        ..color = Colors.black.withOpacity(isDayTime ? 0.5 : 0.3)
        ..style = PaintingStyle.stroke
        ..strokeWidth = 1.0;

      canvas.drawRect(
        Rect.fromCenter(
          center: blockData.position,
          width: blockData.blockSize * blockData.scale,
          height: blockData.blockSize * blockData.scale,
        ),
        borderPaint,
      );

      // 添加简单的阴影效果
      if (isDayTime) {
        final shadowPaint = Paint()
          ..color = Colors.black.withOpacity(0.2)
          ..style = PaintingStyle.fill;

        canvas.drawRect(
          Rect.fromLTWH(
            blockData.position.dx + blockData.blockSize * blockData.scale * 0.1,
            blockData.position.dy + blockData.blockSize * blockData.scale * 0.1,
            blockData.blockSize * blockData.scale * 0.8,
            blockData.blockSize * blockData.scale * 0.8,
          ),
          shadowPaint,
        );
      }
    }

    // 绘制动物
    for (var animal in animals) {
      final dx = (animal.x - cameraX) * 30.0;
      final dy = (animal.y - cameraY) * 30.0;

      // 根据动物类型设置颜色
      switch (animal.type) {
        case 0: // 羊
          paint.color = Colors.white;
          break;
        case 1: // 猪
          paint.color = Colors.pink.shade200;
          break;
        case 2: // 鸡
          paint.color = Colors.brown.shade300;
          break;
      }

      // 绘制动物身体
      canvas.drawCircle(Offset(dx, dy), 15, paint);

      // 绘制动物头部
      canvas.drawCircle(Offset(dx, dy - 10), 10, paint);

      // 绘制动物眼睛
      final eyePaint = Paint()..color = Colors.black;
      canvas.drawCircle(Offset(dx - 3, dy - 12), 2, eyePaint);
      canvas.drawCircle(Offset(dx + 3, dy - 12), 2, eyePaint);
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}
